package fr.upmc.aladyn.transactionables.saveobject;

import java.util.Set;
import java.util.Stack;


/**
 * <p>Singleton used to manage all the SaveRestoreObjects by stacking them into StackOfSaveRestoreObjects.</p>
 * @author Alexis Deluze
 *
 */
public class StackManager {
	private static StackManager stackManager;
	private static Stack<StackOfSaveRestoreObjects> pile;
	private static boolean isInit;

	/**
	 * <p>Singleton to get the StackManager</p>
	 * @return the StackManager
	 */
	public static StackManager getStackManager() {
		if (stackManager == null) {
			stackManager = new StackManager();
			System.out.println("[STACK MANAGER] Creation du StackManager");
			pile = new Stack<StackOfSaveRestoreObjects>();
			isInit = false;
		}
		//System.out.println("[STACK MANAGER] Taille de la pile : "+pile.size());
		return stackManager;
	}

	/**
	 * <p>Create a new Stack element</p>
	 */
	public void newStackBlock() {
		System.out.println("[STACK MANAGER] Ajout d'un bloc de sauvegarde");
		isInit = true;
		StackOfSaveRestoreObjects setSRO = new StackOfSaveRestoreObjects();
		pile.push(setSRO);
	}

	/**
	 * <p>Delete the last element of the Stack</p>
	 */
	public void pop() {
		System.out.println("[STACK MANAGER] Supression d'un bloc de sauvegarde");
		isInit = false;
		pile.pop();
	}

	/**
	 * <p>Restore the Objects previously saved of the last element of the Stack</p>
	 */
	public void restore() {
		System.out.println("[STACK MANAGER] Restoration");
		while(! pile.lastElement().getStack().isEmpty()){
			pile.lastElement().removeLast().restore();
		}
	}

	/**
	 * <p>Save an Object into the last element of the Stack</p>
	 * @param o The Object to save
	 */
	public void save(Object o) {
		if(isInit){
			Set<Integer> lastSROindex = pile.lastElement().getIndex();
			if(! lastSROindex.contains(o.hashCode())){
				System.out.println("[STACK MANAGER] Sauvegarde");
				SaveRestoreObject sro = new SaveRestoreObject(o);
				sro.save();
				pile.lastElement().add(sro);
			}
		}
	}
}
